package com.apestech.framework.metadata;

import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;

import com.apestech.framework.json.JSONObject;

/**
 * SQL执行媒体包
 * @author hupo
 *
 */
public class SqlMetaData implements ResultSetMetaData {
	
	private final ResultSetMetaData rsd;
	private JSONObject fieldMap=null;
	private String[] columns;
	private String field="";
	
	public SqlMetaData(ResultSetMetaData rsd) throws SQLException{
		this.rsd=rsd;
		init();
	}
	
	/**
	 * 获取JSON格式的字段信息
	 * @return
	 */
	public JSONObject getFieldJson(){
		return this.fieldMap;
	}
	
	/**
	 * 获取字段列表
	 * @return
	 */
	public String[] getColumns(){
		return this.columns;
	}
	
	/**
	 * 带;分割符方式输出字串类型的字段名合集
	 */
	public String getFieldString(){
		return this.field;
	}
	
	/**
	 * 初始化所有字段信息
	 * @throws SQLException
	 */
	private void init() throws SQLException{
		fieldMap =new JSONObject();
		field="";
		if(rsd==null){
			return;
		}
		int len=rsd.getColumnCount();
		for(int i=1; i<=len; i++){
			JSONObject map=new JSONObject();
			String ColumnName=rsd.getColumnName(i);
			map.put("CLASSNAME", rsd.getColumnClassName(i));
			map.put("COLUMN_NAME", rsd.getColumnName(i));
			int NULL=rsd.isNullable(i);
			if(NULL==0){
				map.put("NOTNULL", "1");
			}
			String TYPE_NAME=rsd.getColumnTypeName(i);
			map.put("TYPE_NAME", TYPE_NAME);
			if("VARCHAR2".equals(TYPE_NAME)){
				map.put("LENGTH", rsd.getPrecision(i));
			} else if("NUMBER".equals(TYPE_NAME)){
				map.put("LENGTH", rsd.getPrecision(i));
				map.put("SIZE", rsd.getScale(i));
			}
			
			fieldMap.put(ColumnName, map);
			if(!"".equals(field)){
				field=field+";";
			}
			field=field+ColumnName;
		}
		columns=field.split(";");
		if(!"".equals(field)){
			field=";"+field;
		}
	}
	
	/**
	 * 根据字段名获取对应ClassName
	 * @param fieldName
	 * @return
	 * @throws Exception
	 */
	public String getColumnClassName(String fieldName) throws Exception {
		if(this.fieldMap.getJSONObject(fieldName)==null){
			return null;
		}
		return this.fieldMap.getJSONObject(fieldName).getString("ClassName");
	}
	
	/**
	 * 根据字段名获取对应ColumnLabel
	 * @param fieldName
	 * @return
	 * @throws Exception
	 */
	public String getColumnLabel(String fieldName) throws Exception {
		if(this.fieldMap.getJSONObject(fieldName)==null){
			return null;
		}
		return this.fieldMap.getJSONObject(fieldName).getString("ColumnLabel");
	}
	
	/**
	 * 根据字段名获取对应Precision
	 * @param fieldName
	 * @return
	 * @throws Exception
	 */
	public int getPrecision(String fieldName) throws Exception {
		if(this.fieldMap.getJSONObject(fieldName)==null){
			return 0;
		}
		return this.fieldMap.getJSONObject(fieldName).getIntValue("Precision");
	}

	/**
	 * 根据字段名获取对应Scale
	 * @param fieldName
	 * @return
	 * @throws Exception
	 */
	public int getScale(String fieldName) throws Exception {
		if(this.fieldMap.getJSONObject(fieldName)==null){
			return 0;
		}
		return this.fieldMap.getJSONObject(fieldName).getIntValue("Scale");
	}
	
	/**
	 * 根据字段名获取对应isNullable
	 * @param fieldName
	 * @return
	 * @throws Exception
	 */
	public int isNullable(String fieldName) throws Exception {
		if(this.fieldMap.getJSONObject(fieldName)==null){
			return 0;
		}
		return this.fieldMap.getJSONObject(fieldName).getIntValue("isNullable");
	}	

	/*原生方法*/
	public boolean isWrapperFor(Class<?> arg0) throws SQLException {
		return this.rsd.isWrapperFor(arg0);
	}

	public <T> T unwrap(Class<T> arg0) throws SQLException {
		return this.rsd.unwrap(arg0);
	}

	public String getCatalogName(int arg0) throws SQLException {
		return this.rsd.getCatalogName(arg0);
	}

	public String getColumnClassName(int arg0) throws SQLException {
		return this.rsd.getColumnClassName(arg0);
	}

	public int getColumnCount() throws SQLException {
		return this.rsd.getColumnCount();
	}

	public int getColumnDisplaySize(int arg0) throws SQLException {
		return this.rsd.getColumnDisplaySize(arg0);
	}

	public String getColumnLabel(int arg0) throws SQLException {
		return this.rsd.getColumnLabel(arg0);
	}

	public String getColumnName(int arg0) throws SQLException {
		return this.rsd.getColumnName(arg0);
	}

	public int getColumnType(int arg0) throws SQLException {
		return this.rsd.getColumnType(arg0);
	}

	public String getColumnTypeName(int arg0) throws SQLException {
		return this.rsd.getColumnTypeName(arg0);
	}

	public int getPrecision(int arg0) throws SQLException {
		return this.rsd.getPrecision(arg0);
	}

	public int getScale(int arg0) throws SQLException {
		return this.rsd.getScale(arg0);
	}

	public String getSchemaName(int arg0) throws SQLException {
		return this.rsd.getSchemaName(arg0);
	}

	public String getTableName(int arg0) throws SQLException {
		return this.rsd.getTableName(arg0);
	}

	public boolean isAutoIncrement(int arg0) throws SQLException {
		return this.rsd.isAutoIncrement(arg0);
	}

	public boolean isCaseSensitive(int arg0) throws SQLException {
		return this.rsd.isCaseSensitive(arg0);
	}

	public boolean isCurrency(int arg0) throws SQLException {
		return this.rsd.isCurrency(arg0);
	}

	public boolean isDefinitelyWritable(int arg0) throws SQLException {
		return this.rsd.isDefinitelyWritable(arg0);
	}

	public int isNullable(int arg0) throws SQLException {
		return this.rsd.isNullable(arg0);
	}

	public boolean isReadOnly(int arg0) throws SQLException {
		return this.rsd.isReadOnly(arg0);
	}

	public boolean isSearchable(int arg0) throws SQLException {
		return this.rsd.isSearchable(arg0);
	}

	public boolean isSigned(int arg0) throws SQLException {
		return this.rsd.isSigned(arg0);
	}

	public boolean isWritable(int arg0) throws SQLException {
		return this.rsd.isWritable(arg0);
	}
	
	/*原生方法*/

}
